use crate::lexer::Lexer;
use crate::token::{Token, TokenKind};

// ----------------------
// AST 节点定义
// ----------------------
#[derive(Debug, PartialEq)]
pub enum Expr {
   Number(f64),
   Prefix(TokenKind, Box<Expr>),
   Infix(TokenKind, Box<Expr>, Box<Expr>),
   Grouped(Box<Expr>),
}

impl Expr {
   pub fn evaluate(&self) -> f64 {
      match self {
         Expr::Number(n) => *n,
         Expr::Prefix(kind, expr) => {
            let val = expr.evaluate();
            match kind {
               TokenKind::Minus => -val,
               _ => panic!("不支持的符号运算符"),
            }
         }
         Expr::Infix(kind, left, right) => {
            let l = left.evaluate();
            let r = right.evaluate();
            match kind {
               TokenKind::Plus => l + r,
               TokenKind::Minus => l - r,
               TokenKind::Asterisk => l * r,
               TokenKind::Slash => l / r,
               TokenKind::Caret => l.powf(r),
               _ => panic!("不支持的中缀运算符: {:?}", kind),
            }
         }
         Expr::Grouped(expr) => expr.evaluate(),
      }
   }
}

#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
enum Precedence {
   Lowest = 0,
   Sum = 1,     // + -
   Product = 2, // * / %
   Power = 3,   // ^
   Prefix = 4,  // 前缀运算符（如负号）
}

// 运算符优先级映射
fn precedence_map(kind: &TokenKind) -> Precedence {
   match kind {
      TokenKind::Plus | TokenKind::Minus => Precedence::Sum,
      TokenKind::Asterisk | TokenKind::Slash => Precedence::Product,
      TokenKind::Caret => Precedence::Power,
      _ => Precedence::Lowest,
   }
}

pub struct Parser<'a> {
   lexer: Lexer<'a>,
   current_token: Token,
}

impl<'a> Parser<'a> {
   pub fn new(mut lexer: Lexer<'a>) -> Self {
      let current_token = lexer.next_token();
      Self {
         lexer,
         current_token,
      }
   }

   pub fn parse(&mut self) -> Expr {
      self.parse_expression(Precedence::Lowest)
   }

   fn parse_expression(&mut self, precedence: Precedence) -> Expr {
      let mut left = self.parse_prefix();

      while precedence < self.current_precedence() {
         if let Some(infix_kind) = self.parse_infix() {
            self.advance();
            let right =
               self.parse_expression(self.token_precedence(&infix_kind));
            left = Expr::Infix(infix_kind, Box::new(left), Box::new(right));
         } else {
            break;
         }
      }

      left
   }

   // 解析前缀表达式（数字、括号、负号）
   fn parse_prefix(&mut self) -> Expr {
      match self.current_token.kind {
         TokenKind::Number(n) => {
            let expr = Expr::Number(n);
            self.advance();
            expr
         }
         TokenKind::Minus => {
            self.advance();
            let expr = self.parse_expression(Precedence::Prefix);
            Expr::Prefix(TokenKind::Minus, Box::new(expr))
         }
         TokenKind::LParen => {
            self.advance();
            let expr = self.parse_expression(Precedence::Lowest);
            self.expect(TokenKind::RParen);
            Expr::Grouped(Box::new(expr))
         }
         _ => panic!("Unexpected token: {:?}", self.current_token),
      }
   }

   // 解析中缀运算符
   fn parse_infix(&mut self) -> Option<TokenKind> {
      match self.current_token.kind {
         TokenKind::Plus
         | TokenKind::Minus
         | TokenKind::Asterisk
         | TokenKind::Slash
         | TokenKind::Caret => Some(self.current_token.kind.clone()),
         _ => None,
      }
   }

   // 获取当前 token 优先级
   fn current_precedence(&self) -> Precedence {
      self.token_precedence(&self.current_token.kind)
   }

   // 运算符优先级映射
   fn token_precedence(&self, kind: &TokenKind) -> Precedence {
      precedence_map(kind)
   }

   // 移动到下一个 token
   fn advance(&mut self) {
      self.current_token = self.lexer.next_token();
   }

   // 校验当前 token
   fn expect(&mut self, kind: TokenKind) {
      if self.current_token.kind == kind {
         self.advance();
      } else {
         panic!("Expected {:?}, found {:?}", kind, self.current_token.kind);
      }
   }
}
